home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
keyb
/
keymap00.zip
/
KEYMAP.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-10-16
|
6KB
|
304 lines
;; keymap.asm v0.0
;; Custom Keymap Driver
;; Copyright (C) 1991 Kenneth Gober
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program; if not, write to the Free Software
;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
;;
;; To contact the author about changes, enhancements, bug reports, or
;; other comments, send electronic mail to:
;;
;; snow@drycas (from Bitnet sites)
;; snow@drycas.club.cc.cmu.edu (from Internet sites)
;;
;; If you are unable to contact the author through electronic mail,
;; try sending a letter (as a last resort, only) to the following address:
;;
;; Kenneth Gober
;; 412 Robin Road
;; Cedar Hill, TX 75104 (USA)
;;
;; Please note that mail sent to this address may not yield a response
;; for several months!
;;
;; Version History:
;;
;; 0.0 Initial release
;;
ideal ; Use TASM Ideal mode syntax
p286n ; Assemble for the 80286 (real mode)
locals $$ ; local labels preceded by '$$'
NMAPS = (kmend-maptab)/96 ; number of keyboard layouts installed
kEsc = 1 ; list of keyboard scan codes
k1 = 2
k2 = 3
k3 = 4
k4 = 5
k5 = 6
k6 = 7
k7 = 8
k8 = 9
k9 = 10
k0 = 11
kMinus = 12
kEqual = 13
kBS = 14
kTab = 15
kQ = 16
kW = 17
kE = 18
kR = 19
kT = 20
kY = 21
kU = 22
kI = 23
kO = 24
kP = 25
kOpen = 26
kClose = 27
kEnter = 28
kCtrl = 29
kA = 30
kS = 31
kD = 32
kF = 33
kG = 34
kH = 35
kJ = 36
kK = 37
kL = 38
kColon = 39
kQuote = 40
kTilde = 41
kLShift = 42
kPipe = 43
kZ = 44
kX = 45
kC = 46
kV = 47
kB = 48
kN = 49
kM = 50
kComma = 51
kDot = 52
kSlash = 53
kRShift = 54
kStar = 55
kAlt = 56
kSpace = 57
kCaps = 58
kF1 = 59
kF2 = 60
kF3 = 61
kF4 = 62
kF5 = 63
kF6 = 64
kF7 = 65
kF8 = 66
kF9 = 67
kF10 = 68
kNum = 69
kScroll = 70
kp7 = 71
kp8 = 72
kp9 = 73
kpMinus = 74
kp4 = 75
kp5 = 76
kp6 = 77
kpPlus = 78
kp1 = 79
kp2 = 80
kp3 = 81
kp0 = 82
kpDot = 83
kpSysRq = 84
kF11 = 87
kF12 = 88
rhds equ (rh ds:si)
rhes equ (rh es:di)
macro pushfm
pushf
push cs
endm
macro popfm
call iretm
endm
struc rh ; request header
len db ?
dev db ?
cmd db ?
st dw ?
rsvd dq ?
ct db ?
aoff dw ?
aseg dw ?
dptr dd ?
ends
segment code use16
devhdr dd -1 ; device header
devflg dw 0a000h
devstr dw kmstr
devint dw kmint0
devnam db '-KEYMAP-'
mapoff dw maptab ; pointer to active keymap
align 4 ; align rhptr on a dword boundary
label rhptr dword ; pointer to request header
rhoff dw ?
rhseg dw ?
proc kmstr far ; strategy routine
assume cs:code
mov [rhoff], bx
mov [rhseg], es
ret
endp
proc kmint far ; resident interrupt routine
assume cs:code
push si ; save registers
push ds
lds si, [rhptr] ; ds:si = request header
mov [rhds.st], 8103h ; return error (unknown command)
pop ds ; restore registers
pop si
ret
endp
label hdrend unknown ; HEADER SECTION ENDS HERE
align 4 ; align ptrs on a dword boundary
label intptr dword ; pointer to interrupt handler
intoff dw 15h*4
intseg dw 0
proc kmmap far ; interrupt handler
assume cs:code
pushfm ; push flags
cmp ah, 4fh ; is it keyboard intercept?
je short $$1
popfm ; pop flags
jmp [intptr] ; chain to old handler
$$1: push ds ; save registers
push bx
push ax ; save original scancode
and al, 7fh ; mask break bit
cmp al, 96 ; in range?
jae short keyok
cmp al, kF1 ; keymap select key?
jb short xlate
cmp al, kF1+NMAPS
jae short xlate
xor bx, bx ; valid function key
mov ds, bx ; check shift keys
mov bl, [ds:417h]
and bl, 0eh ; alt-ctrl-leftshift
cmp bl, 0eh
jne short xlate
sub ax, 4f00h+kF1 ; change maps
imul bx, ax, 96 ; 98 keys per map
lea bx, [ds:maptab+bx] ; maps start at maptab
mov [cs:mapoff], bx
pop ax ; restore original scancode
pop bx ; restore registers
pop ds
popfm ; pop flags
clc ; but clear carry to ignore this key
ret 2 ; don't restore flags on IRET
xlate: mov bx, [cs:mapoff] ; ds:bx = keymap
pop ax ; restore original scancode
mov ah, al
and ah, 80h ; save make/break bit in ah
and al, 7fh ; look up scancode
xlat [cs:0]
or al, ah ; restore make/break bit
mov ah, 4fh ; restore unused registers
done: pop bx ; restore registers
pop ds
popfm ; pop flags
iretm: iret
keyok: pop ax ; no translation necessary
jmp short done ; restore scancode and return
endp
label maptab unknown ; keymap tables
include "sholes.kbd" ; default keymap
include "dvorak.kbd" ; alternate keymap (up to 9)
label kmend unknown ; RESIDENT PORTION ENDS HERE
proc kmint0 far ; initial interrupt routine
assume cs:code, ds:code
pushfm ; save flags
pusha ; save registers
push ds
push es
push cs
pop ds
les di, [rhptr] ; es:di = request header
mov [rhes.st], 8103h ; assume error (unknown command)
mov al, [rhes.cmd] ; only cmd 0, INIT is legal
or al, al
jnz short exit
mov ah, 9 ; write banner
mov dx, offset eHello
int 21h
mov [devint], offset kmint ; install resident interrupt routine
mov [rhes.aseg], cs ; discard initialization section
mov [rhes.aoff], offset kmend
mov [rhes.st], 0100h ; return success code
les di, [intptr] ; hook into INT 15 vector
mov ax, [es:di] ; save old offset
mov [intoff], ax
mov ax, [es:di+2] ; save old segment
mov [intseg], ax
cli ; disable interrupts and hook in
mov [word es:di], offset kmmap
mov [es:di+2], cs
exit: pop es ; restore registers
pop ds
popa
popfm ; pop flags
ret
endp
eHello db 'Custom Keymap Driver v0.0', 13, 10
db 'Copyright (C) 1991 Kenneth Gober'
eNL db 13, 10, 13, 10, '$'
ends code
end